package com.nchu.chatserver.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.nchu.chatserver.dao.ContactUserDTO;
import com.nchu.chatserver.dao.MessageCountResult;
import com.nchu.chatserver.dao.UserDTO;
import com.nchu.chatserver.entity.Contact;
import com.nchu.chatserver.entity.Message;
import com.nchu.chatserver.entity.User;
import com.nchu.chatserver.mapper.ContactMapper;
import com.nchu.chatserver.mapper.MessageMapper;
import com.nchu.chatserver.mapper.UserMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Created with IntelliJ IDEA.
 *
 * @Author: 王小航
 * @Date: 2025/05/07/22:21
 * @Description:
 */
@Service
@RequiredArgsConstructor
public class ContactServiceImpl implements ContactService {
    private final UserMapper userMapper;
    private final ContactMapper contactMapper;
private final MessageMapper messageMapper;

    @Override
    public List<UserDTO> getContacts(Integer userId) {


        // 构造查询条件，获取联系人 ID 列表
        QueryWrapper<Contact> queryWrapper = new QueryWrapper<>();

        queryWrapper.eq("user_id", userId)
                .or()
                .eq("contact_id", userId);
        /// 使用 selectList 查询联系人 ID 列表
        List<Contact> contacts = contactMapper.selectList(queryWrapper);

        // 提取所有不同的 user_id 和 contact_id
        Set<Integer> contactIds = new HashSet<>();
        for (Contact contact : contacts) {
            if (!contact.getUserId().equals(userId)) {
                contactIds.add(contact.getUserId());
            }
            if (!contact.getContactId().equals(userId)) {
                contactIds.add(contact.getContactId());
            }
        }

        // 如果没有联系人，直接返回空列表
        if (contactIds.isEmpty()) {
            return Collections.emptyList();
        }

        // 查询联系人详细信息
        List<User> users = userMapper.selectBatchIds(contactIds);


        return users.stream()
                .map(user -> {
                    UserDTO dto = new UserDTO();
                    dto.setId(user.getId());
                    dto.setUsername(user.getUsername());
                    dto.setIp(user.getIp());
                    dto.setIsOnline(user.getIsOnline());
                    // 其他字段...
                    return dto;
                })
                .collect(Collectors.toList());
    }


    @Override
    public List<ContactUserDTO> getContactsAndUnread(Integer userId) {
        // 构造查询条件，获取联系人 ID 列表
        QueryWrapper<Contact> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId)
                .or()
                .eq("contact_id", userId);

        // 查询联系人关系列表
        List<Contact> contacts = contactMapper.selectList(queryWrapper);

        // 提取所有不同的联系人ID（排除当前用户）
        Set<Integer> contactIds = new HashSet<>();
        for (Contact contact : contacts) {
            if (!contact.getUserId().equals(userId)) {
                contactIds.add(contact.getUserId());
            }
            if (!contact.getContactId().equals(userId)) {
                contactIds.add(contact.getContactId());
            }
        }

        // 如果没有联系人，直接返回空列表
        if (contactIds.isEmpty()) {
            return Collections.emptyList();
        }

        // 查询联系人详细信息
        List<User> users = userMapper.selectBatchIds(contactIds);

        // 构建联系人ID到用户信息的映射
        Map<Integer, User> userMap = users.stream()
                .collect(Collectors.toMap(User::getId, user -> user));

        // 批量查询每个联系人的未读消息数量
        Map<Integer, Integer> unreadCountMap = getUnreadMessageCount(userId, contactIds);

        // 转换为DTO并设置未读消息数
        return contactIds.stream()
                .filter(userMap::containsKey) // 确保用户存在
                .map(contactId -> {
                    User user = userMap.get(contactId);
                    ContactUserDTO dto = new ContactUserDTO();
                    dto.setId(user.getId());
                    dto.setUsername(user.getUsername());
                    dto.setIp(user.getIp());
                    dto.setIsOnline(user.getIsOnline());
                    // 设置未读消息数，默认为0
                    dto.setUnreadCount(unreadCountMap.getOrDefault(contactId, 0));
                    return dto;
                })
                .collect(Collectors.toList());
    }

    /**
     * 批量获取与指定联系人的未读消息数量
     */
    /**
     * 使用MyBatis-Plus统计未读消息数量
     */
    private Map<Integer, Integer> getUnreadMessageCount(Integer userId, Set<Integer> contactIds) {
        // 构建SQL查询条件，使用正确的字段名sender_id和receiver_id
        QueryWrapper<Message> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("sender_id", "COUNT(*) as count")
                .in("sender_id", contactIds)
                .eq("receiver_id", userId)
                .eq("is_read", false) // 使用is_read字段和布尔值
                .groupBy("sender_id");

        // 执行查询并处理结果
        return messageMapper.selectMaps(queryWrapper).stream()
                .collect(Collectors.toMap(
                        map -> (Integer) map.get("sender_id"),
                        map -> Integer.parseInt(map.get("count").toString()),
                        (existing, replacement) -> existing
                ));
    }
    @Override
    public UserDTO addContact(Integer userId, String contactUsername) {
        // 检查联系人是否存在
        User contactUser = userMapper.selectOne(new QueryWrapper<User>().eq("username", contactUsername));
        if (contactUser == null) {
            throw new RuntimeException("用户不存在");
        }

        // 检查是否已经是联系人
        QueryWrapper<Contact> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId)
                .eq("contact_id", contactUser.getId());
        if (contactMapper.exists(queryWrapper)) {
            throw new RuntimeException("已是联系人");
        }
        // 添加双向联系人关系
        Contact contact = new Contact();
        contact.setUserId(userId);
        contact.setContactId(contactUser.getId());
        contact.setCreatedAt(LocalDateTime.now());
        contactMapper.insert(contact);

        // 添加反向联系人关系（如果需要双向关系）
        Contact reverseContact = new Contact();
        reverseContact.setUserId(contactUser.getId());
        reverseContact.setContactId(userId);
        reverseContact.setCreatedAt(LocalDateTime.now());
        contactMapper.insert(reverseContact);
        // 手动转换 User 到 UserDTO
        UserDTO userDTO = new UserDTO();
        userDTO.setId(contactUser.getId());
        userDTO.setUsername(contactUser.getUsername());
        userDTO.setIsOnline(contactUser.getIsOnline());
        // 如果 UserDTO 还有其他字段，继续补充映射

        // 返回联系人信息
        return userDTO;

    }

    @Override
    public void removeContact(Integer userId, Integer contactId) {

        // 删除正向联系人关系
        QueryWrapper<Contact> queryWrapper = new QueryWrapper<>();
    queryWrapper.eq("user_id", userId)
               .eq("contact_id", contactId); // 添加contactId条件
        contactMapper.delete(queryWrapper);

        // 删除反向联系人关系
        QueryWrapper<Contact> reverseQueryWrapper = new QueryWrapper<>();
    reverseQueryWrapper.eq("user_id", contactId) // 注意这里是contactId作为user_id
                     .eq("contact_id", userId); // 这里是userId作为contact_id
        contactMapper.delete(reverseQueryWrapper);

    }

    @Override
    public boolean isContact(Integer userId, Integer contactId) {
        // 构造查询条件
        QueryWrapper<Contact> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("contact_id") // 只查询 contact_id 字段
                .eq("user_id", userId); // 指定用户 ID

        // 调用 exists 方法判断是否存在联系人关系
        return contactMapper.exists(queryWrapper);
    }


}